package com.zb.service.impl;

import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.zb.constant.AccountConstant;
import com.zb.entity.AdmInfo;
import com.zb.entity.LoginToken;
import com.zb.enums.DeviceType;
import com.zb.exception.LoginException;
import com.zb.redis.RedisLoginTokenUtil;
import com.zb.service.RefreshTokenService;
import org.springframework.stereotype.Service;

/**
 * @Author WEN
 * @Date 2023/7/10 0010
 **/
@Service
public class RefreshTokenServiceImpl implements RefreshTokenService {

    // 刷新token
    @Override
    public LoginToken refreshToken(String refreshToken) throws LoginException {
        if (!RedisLoginTokenUtil.hasAccessTokenByRefreshToken(refreshToken)) {
            throw new LoginException("登录已过期，请重新登录！");
        }

        // 旧token
        String oldAccessToken = RedisLoginTokenUtil.getAccessTokenByRefreshToken(refreshToken);
        AdmInfo admInfo = RedisLoginTokenUtil.getAdmInfoByAccessToken(oldAccessToken);

        // 重新登录
        if (admInfo.isRememberMe()) {
            StpUtil.login(admInfo.getId(),
                    new SaLoginModel()
                            .setDevice(admInfo.getDevice()) // 登录设备
                            .setIsLastingCookie(admInfo.isRememberMe()) // 记住我
                            .setTimeout(AccountConstant.LOGIN_TOKEN_REMEMBERME_EXPIRE_TIME) // 七天有效期
            );
        } else {
            StpUtil.login(admInfo.getId(), admInfo.getDevice());
        }
        // 获取登录信息
        SaTokenInfo saToken = StpUtil.getTokenInfo();

        // 封装登录信息返回给前端
        LoginToken loginToken = new LoginToken(
                saToken.getTokenName(),
                saToken.getTokenValue(),
                RedisLoginTokenUtil.generatorRefreshToken(),
                saToken.getTokenTimeout()
        );
        RedisLoginTokenUtil.setAdmInfoByAccessToken(saToken.getTokenValue(), admInfo);
        RedisLoginTokenUtil.setRefreshTokenByAccessToken(loginToken.getTokenValue(), loginToken.getRefreshToken(), admInfo.isRememberMe());
        RedisLoginTokenUtil.setAccessTokenByRefreshToken(loginToken.getRefreshToken(), loginToken.getTokenValue(), admInfo.isRememberMe());

        // 删除旧的登录缓存信息
        RedisLoginTokenUtil.removeAllTokenByAccessToken(oldAccessToken);
        RedisLoginTokenUtil.removeLoginAccessToken(oldAccessToken);
        return loginToken;
    }
}
